package com.wideplay.warp.security;

import com.google.inject.Inject;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.springframework.beans.factory.InitializingBean;

import javax.servlet.Filter;
import javax.servlet.ServletException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * On: 17/10/2007
 *
 * This is an impl of the configuration interface. This impl is not threadsafe
 * and start must only be invoked once.
 *
 * @author Dhanji R. Prasanna
 * @since 1.0
 */
@ThreadSafe
class AcegiSecurityService extends SecurityService {
    private final SimpleConfig config;
    private final List<Filter> filterChain; //the target filter chain is partially injected...
    private final SecurityConfigurationBuilder builder;

    @GuardedBy("this")
    private boolean started;

    @Inject
    AcegiSecurityService(SimpleConfig config, @Filters List<Filter> filterChain, SecurityConfigurationBuilder builder) {
        this.config = config;
        this.filterChain = filterChain;
        this.builder = builder;
    }

    public synchronized void start() {
        if (started)
            throw new IllegalStateException("SecurityService was already started");

        try {
            //add to the main filter chain
            filterChain.addAll(builder.build());

        } catch (ServletException e) {
            throw new ConfigurationException("Could not build filter pipeline due to a configuration fault", e);
        }

        //start up registered services
        for (Filter filter : filterChain) {
            if (filter instanceof InitializingBean)
                try {
                    ((InitializingBean)filter).afterPropertiesSet();
                } catch (Exception e) {
                    throw new ConfigurationException("Unable to start a managed filter or component", e);
                }
        }

        //looks like everything was started up ok...
        started = true;
    }
}
